#include "socket_basic.hpp"

class UDPServer : public socket_basic
{
public:
    UDPServer(uint16_t port) : socket_basic(port, INADDR_ANY)
    {
        ssize_t n = bind(_sockfd, reinterpret_cast<const sockaddr *>(&_addr), sizeof(_addr));
        if (n == -1)
        {
            _log(FATAL, __LINE__, __FILE__, "server bind error!\n");
            exit(BIND_ERR);
        }
    }
    void Load(std::string filePath)
    {
        std::ifstream file(filePath);
        std::string line;
        while (std::getline(file, line))
        {
            size_t len = 0;
            for (auto &ch : line)
            {
                if (ch == ' ')
                {
                    std::string english(line,0,len);
                    _dict[english] = std::string(line,len+3);
                    break;
                }
                len++;
            }
        }
    }
    void Start()
    {
        while (true)
        {
            socklen_t size = sizeof(_addr);
            char buffer[1024];
            memset(static_cast<void *>(buffer), 0, sizeof(buffer));
            ssize_t n = recvfrom(_sockfd, buffer, 1024, MSG_WAITALL, reinterpret_cast<sockaddr *>(&_addr), &size);
            if (n > 0)
            {
                std::cout << "receipt message:" << buffer << std::endl;
                socklen_t addr_len = sizeof(_addr);
                std::string val;
                auto it = _dict.find(std::string(buffer));
                if(it == _dict.end())
                {
                    val = "Unknow!";
                }
                else 
                {
                    val = it->second;
                }
                n = sendto(_sockfd, val.c_str(), strlen(val.c_str()), 0, reinterpret_cast<const sockaddr *>(&_addr), addr_len);
            }
            sleep(1);
        }
    }

private:
    std::unordered_map<std::string, std::string> _dict;
};
void Usage(std::string use)
{
    std::cout << "Usage:\n\r " << " " << use << " " << "local_port" << std::endl;
}

int main(int argc, char *argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        exit(-1);
    }
    uint16_t port = static_cast<uint16_t>(std::stoi(argv[1]));

    UDPServer udp(port);
    udp.Load("./dict.txt");
    udp.Start();
    return 0;
}
